package com.baigt.juc.base;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

/**
 * 类功能描述:
 * 线程通信
 * wait的特点是：和interrupt一样会擦除中断标识(和sleep一样是可中断方法，能接收中断信号)
 *
 * @author baigt
 * @version V1.0
 * @since 2019-10-21 10:25
 */
public class ThreadRun06 {
    public static void main(String[] args) throws InterruptedException {
        final EventQueue queue = new EventQueue();
        new Thread(() -> {
            for (; ; ) {
                queue.offer(new EventQueue.Event());
            }
        }, "Producer").start();
        new Thread(() -> {
            for (; ; ) {
                queue.take();
                try {
                    TimeUnit.MILLISECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer").start();
    }

}

class EventQueue {
    //默认大小
    private final int max = 10;

    static class Event {
    }

    private final LinkedList<Event> eventQueue = new LinkedList<>();

    public EventQueue() {
    }

    public void offer(Event event) {
        synchronized (eventQueue) {
            // 这里为啥不用if？？  用if有什么问题？
            while (eventQueue.size() >= max) {
                try {
                    System.out.println(Thread.currentThread().getName() + " is full");
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " add success");
            eventQueue.addLast(event);
            //用nofify有什么问题？
            eventQueue.notifyAll();
        }
    }

    public void take() {
        synchronized (eventQueue) {
            // 同上  用if会怎么样？
            while (eventQueue.isEmpty()) {
                try {
                    System.out.println(Thread.currentThread().getName() + " is empty");
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " remove success");
            eventQueue.removeFirst();
            // 同上
            eventQueue.notifyAll();

        }
    }
}

/**
 * testwait方法什么问题？
 */
class UseWaitDemo {
    private final Object MUTEX = new Object();

    /**
     * 需要持有锁才能使用 wait方法
     * synchronized(this){}
     */
    private void testwait() {
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 持有锁要和notify的一致才行
     * 这里应该是持有的应该是this
     */
    private synchronized void testwait2() {
        try {
            MUTEX.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
